//
// Created by jmdvirus on 2020/3/12 下午2:42.
// Copyright (c) 2020 benewtech All rights reserved.
//
//     ******          *             *--*
//       ||            *             |
//       ||  *--*--*---*  * *-********--*
//   *  //   *  *  *   *\ / ||  |  |    |
//    **    *  *  *---* *  *   *--* *--*
//

#ifndef CUTEDEVICE_CMMEDIAVIDEO_H
#define CUTEDEVICE_CMMEDIAVIDEO_H

#include <pthread.h>
#include <semaphore.h>

#include <opencv2/opencv.hpp>
#include <vector>

#include "funcs/CMLock.h"
//#define MEDIA_USE_OPENCV
#ifdef MEDIA_USE_OPENCV
#include "funcs/CMMediaOperationOpenCV.h"
#else
#include "funcs/CMMediaOperationRaw.h"
#endif

class CMMediaVideoFunction
{
public:
    virtual int onFrame(const cv::Mat &frame, const cv::Mat &convertFrame) = 0;
    void setName(const char *str)
    {
        m_name = str;
    }
    std::string &getName()
    {
        return m_name;
    }

private:
    std::string m_name;
};

class CMMediaVideo
{
public:
    CMMediaVideo();
    CMMediaVideo(int index);
    ~CMMediaVideo();

    int registerFunc(CMMediaVideoFunction *func);
    int unregisterFunc(CMMediaVideoFunction *func);

    void setSize(int width, int height);

    int open(int index = 0);
    int close();

    void setNeedConvert(bool en)
    {
        m_needConvert = en;
    }

    int getFrame(cv::Mat &frame);

protected:
    pthread_t m_pid;
    friend void *thread_media_video(void *args);
    int thread_once();
    CMMediaOperationBase *m_media;
    cv::Mat m_currentFrame;
    cv::Mat m_convertFrame;
    bool m_stop;
    CMLock m_lock;
    CMLock m_lockFrame;
    CMLock m_lockT;
    pthread_mutexattr_t m_lockAttrT;

    std::vector<CMMediaVideoFunction *> m_funcs;

    bool m_skipFirstFrames;

    int m_videoWidth;
    int m_videoHeight;
    bool m_sizeChanged;
    bool m_needConvert;
};

#endif  // CUTEDEVICE_CMMEDIAVIDEO_H
